-------------------------------------------
--MII controller
--Created By Colin Anderson
--
-------------------------------------------
--************-----------------------------
--current version does not account for nonempty fifos
--(if empty - where to put the next 48 bits?)
---also does not time the wrreq correctly
--need to time with bit48_sent
--************-----------------------------

LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY MiiController IS
	PORT(clk     		: IN   STD_LOGIC;
		frame_done		: IN   STD_LOGIC;	  	
		Bit48_sent		: IN   STD_LOGIC; ---from bit48accum block (high every time 48bit output is sent)
		crc_valid		: IN   STD_LOGIC;
		crc_complete	: IN   STD_LOGIC;
		
		fifo_0_empty	: IN   STD_LOGIC;
        fifo_1_empty	: IN   STD_LOGIC;

		fifo_0_wrreq 	: OUT  STD_LOGIC;
		fifo_1_wrreq 	: OUT  STD_LOGIC;
		fifo_0_rdreq	: OUT  STD_LOGIC;
		fifo_1_rdreq	: OUT  STD_LOGIC;
		fifo_0_sclr		: OUT  STD_LOGIC;
		fifo_1_sclr		: OUT  STD_LOGIC;
		
		fifo_select		: OUT  STD_LOGIC;
		buffer_req		: OUT  STD_LOGIC        
        );
END MiiController;

ARCHITECTURE Behavior OF MiiController IS

shared variable CurrentFifo: STD_LOGIC;
shared variable myFrame_done : STD_LOGIC;
shared variable myDataBAD: STD_LOGIC;
shared variable myFifo_0_clearing: STD_LOGIC;
shared variable myFifo_1_clearing: STD_LOGIC;
--shared variable myBufferRequested: STD_LOGIC;
---variable CRCcopy: STD_LOGIC_VECTOR(31 DOWNTO 0);

	BEGIN
	   PROCESS (clk)
		BEGIN
		IF (clk'EVENT AND clk = '1') THEN
			fifo_0_sclr <= '0';
			fifo_1_sclr <= '0';
			--fifo_1_wrreq <= '0';
			--fifo_0_wrreq <= '0';
			--buffer_req <= '0';
			--myDataBAD := '0';
		----------------------	
		---This ensures that the clear fifo signal is held high for a full clock cycle
	--		IF(myFifo_0_clearing = '1')THEN
	--			fifo_0_sclr <= '0';
	--			myFifo_0_clearing:= '0';
	--		END IF;
	--		IF(myFifo_1_clearing = '1')THEN
	--			fifo_1_sclr <= '0';
	--			myFifo_1_clearing:= '0';
	--		END IF;
		-------------------------
			
			-----if the frame is done then wait 12 clock cycles (or accumulate time for 48bits from 4bit increments)
				---then switch to writing the next frame to the other fifo
			---NOTICE: next frame MUST be greater than 48 bits
			IF (frame_done = '1') THEN  
				myFrame_done:= '1';	
			END IF;
			
			IF (crc_complete = '1') THEN 
				IF(crc_valid = '0')THEN
				myDataBAD := '1';	
				END IF;
			END IF;
			
			--if the next 48bit package is ready but it is not the end of the frame
				--->send it to the current fifo being written 
			IF (Bit48_sent = '1')AND(myFrame_done= '0')THEN 
				IF(CurrentFifo = '0')THEN
					fifo_0_wrreq <= '1';
				END IF;
				IF(CurrentFifo = '1')THEN
					fifo_1_wrreq <= '1';
				END IF;			
			END IF;
			
			--*--If the frame is empty make sure to stop reading from it
			IF (fifo_1_empty = '1') THEN
				fifo_1_rdreq <= '0';
			END IF;
			IF (fifo_0_empty = '1') THEN
				fifo_0_rdreq <= '0';
			END IF;
			
			IF((fifo_1_empty = '1')AND(fifo_0_empty = '1'))THEN
			buffer_req<='0';
			
			END IF;
			--*--
			
			---Frame has finished--------------------------------------------------------------------------------------- 
			  ---and the last 48bits from the frame are ready to be put in the fifo
			---this handles changing which fifo is being written to
			IF (myFrame_done = '1')AND(Bit48_sent = '1') THEN 
				myFrame_done := '0';
				---this handles the start of releasing the fifo frame to the buffer (buffer_req)
				IF (myDataBAD = '0') THEN   --IF the data is valid then start requesting for the frame to be placed in the buffer
					--IF (myBufferRequested = '1') THEN  
					---IF(buffer_ready = '0') THEN --if the buffer is not ready
						buffer_req <= '1';    	--send another request
					--ELSE  --if buffer is ready
				--		buffer_req<= '0'; 		--stop sending request
						--myBufferRequested :='0';
						IF(CurrentFifo = '1')THEN  --if it is currently writing to fifo 0
							fifo_1_rdreq <= '1';	--then get the frame from fifo 1
							fifo_select <= '1';
							fifo_1_wrreq <= '0';
						ELSE
							fifo_0_rdreq <= '1';
							fifo_select <= '0';
							fifo_0_wrreq <= '0';
						END IF;
					--END IF;	
					--END IF;
				END IF;
				--switch which fifo is being written to
				IF(CurrentFifo = '0')THEN
					--this handles the clearing of the fifos when the data is not valid
					---frame will be cleared after the whole, nonvalid frame has been put into the fifo so it can all be cleared at once
					--nonvalid frame is not sent to the buffer
					IF(myDataBAD = '1')THEN--data not valid
						myDataBAD := '0';
						fifo_0_sclr <= '1'; --send clear frame for one clock cycle
					END IF;
					fifo_1_wrreq <= '1';
					fifo_0_wrreq <= '0';
					CurrentFifo := '1';
				ELSE
					IF(myDataBAD = '1')THEN--data not valid
						myDataBAD := '0';
						fifo_1_sclr <= '1';
					END IF;
					fifo_1_wrreq <= '0';
					fifo_0_wrreq <= '1';
					CurrentFifo := '0';
				END IF;				
			END IF;
		    -----------------------------------------------------------------------------------------------------------------------
		END IF;
	   END PROCESS;
END Behavior;